package com.aaa.tars.service.impl;

import com.aaa.tars.dao.OrderDao;
import com.aaa.tars.dao.OrderItemDao;
import com.aaa.tars.entity.*;
import com.aaa.tars.service.OrderService;
import com.aaa.tars.service.ScenicService;
import com.aaa.tars.service.TicketService;
import com.aaa.tars.service.VisitorsService;
import com.aaa.tars.util.CustomException;
import com.aaa.tars.util.OrderStateEnum;
import com.aaa.tars.util.OrderUtil;
import com.aaa.tars.util.Page;
import com.aaa.tars.util.ResultStatus;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * @FileName: OrderServiceImpl
 * @Description: 订单服务实现类，提供订单相关的业务逻辑处理
 * @Author: ghz
 * @CreateTime:2025/9/8 15:10
 * @Version:1.0.0
 */
@Service("orderService")
@Log4j2
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderDao orderDao;
    // 注入订单详情DAO
    @Resource
    private OrderItemDao orderItemDao;
    @Resource
    private TicketService ticketService; // 注入门票服务
    @Resource
    private ScenicService scenicService; // 注入景区服务
    @Resource
    private VisitorsService visitorsService;
    @Override
    public Order queryByNo(String orderNo) {
        if (orderNo == null || orderNo.trim().isEmpty()) {
            throw new CustomException(400, "订单号不能为空");
        }
        Order order = orderDao.queryByNo(orderNo);
        if (order == null) {
            throw new CustomException(404, "订单不存在");
        }
        return order;
    }


    @Override
    @Transactional
    public Order queryById(Integer orderId) {
        Order order = orderDao.queryById(orderId);
        if (order == null) {
            throw new CustomException(404, "订单不存在");
        }
        // 1. 已通过Mapper关联游客和订单项
        // 2. 绑定订单项中的门票和景区信息（确保前端能获取到完整的景区名称）
        if (order.getOrderItemList() != null) {
            order.getOrderItemList().forEach(item -> {
                if (item.getTicket() != null) {
                    // 确保门票关联了景区信息
                    if (item.getTicket().getScenic() == null) {
                        Scenic scenic = scenicService.queryById(item.getTicket().getScenicId());
                        item.getTicket().setScenic(scenic);
                    }
                }
            });
        }
        return order;
    }

    @Override
    public PageInfo queryByPage(Page<Order> page) {
        Integer pageNo = page.getPageNo();
        Integer pageSize = page.getPageSize();
        if (pageNo == null || pageNo <= 0 || pageSize == null || pageSize <= 0) {
            throw new CustomException(ResultStatus.ERROR.getStatusCode(), ResultStatus.ERROR.getStatusMessage());
        }
        PageHelper.startPage(pageNo, pageSize);
        PageInfo pageInfo = new PageInfo(orderDao.queryByParam(page.getData()));
        
        // 确保订单项中的门票和景区信息被正确加载
        if (pageInfo.getList() != null) {
            List<Order> orders = pageInfo.getList();
            orders.forEach(order -> {
                if (order.getOrderItemList() != null) {
                    order.getOrderItemList().forEach(item -> {
                        if (item.getTicket() != null) {
                            // 确保门票关联了景区信息
                            if (item.getTicket().getScenic() == null && item.getTicket().getScenicId() != null) {
                                Scenic scenic = scenicService.queryById(item.getTicket().getScenicId());
                                item.getTicket().setScenic(scenic);
                            }
                        }
                    });
                    
                    // 设置订单的景区名称（用于列表显示）
                    if (order.getScenicName() == null || order.getScenicName().isEmpty()) {
                        OrderItem firstItem = order.getOrderItemList().get(0);
                        if (firstItem.getTicket() != null) {
                            if (firstItem.getTicket().getScenic() != null && 
                                firstItem.getTicket().getScenic().getScenicName() != null) {
                                order.setScenicName(firstItem.getTicket().getScenic().getScenicName());
                            }
                        }
                    }
                }
            });
        }
    
        return pageInfo;
    }

    // 新增订单：添加事务，确保订单和详情要么同时成功，要么同时失败
    @Override
    @Transactional  // 确保事务已启用
    public int insert(Order order, List<OrderItem> orderItemList) {
        try {
            // 1. 订单项非空校验（先加日志，确认订单项是否传递）
            log.info("接收的订单项数量：{}", orderItemList == null ? 0 : orderItemList.size());
            if (orderItemList == null || orderItemList.isEmpty()) {
                // 明确异常信息：订单项为空
                throw new CustomException(400, "订单详情不能为空（未接收任何订单项）");
            }
            
            // 处理orderPtype字段，确保不超过数据库限制（CHAR(1)）
            if (order.getOrderPtype() != null) {
                String ptype = order.getOrderPtype();
                // 如果是完整的支付方式名称，则转换为对应的编码
                if ("在线支付".equals(ptype)) {
                    order.setOrderPtype("2");
                } else if ("景区支付".equals(ptype) || "现场支付".equals(ptype)) {
                    order.setOrderPtype("1");
                } else if (ptype.length() > 1) {
                    // 如果仍然超过1个字符，则只取第一个字符
                    order.setOrderPtype(ptype.substring(0, 1));
                    log.warn("订单支付方式字段过长，已自动截取第一个字符: {}", order.getOrderPtype());
                }
            }

            // 2. 原有订单项参数校验（每个校验都加明确信息）
            for (OrderItem item : orderItemList) {
                if (item.getTicketId() == null || item.getTicketId() <= 0) {
                    throw new CustomException(400, "订单项缺少有效门票ID（ticketId不能为空或小于0）");
                }
                if (item.getQuantity() == null || item.getQuantity() <= 0) {
                    throw new CustomException(400, "门票购买数量必须为正整数（ticketId：" + item.getTicketId() + "）");
                }
                if (item.getUnitPrice() == null || item.getUnitPrice().compareTo(BigDecimal.ZERO) < 0) {
                    throw new CustomException(400, "门票单价不能为负数（ticketId：" + item.getTicketId() + "）");
                }

                // 门票有效性校验（加日志+明确信息）
                Ticket ticket = ticketService.queryById(item.getTicketId());
                log.info("查询门票结果：ticketId={}, 门票是否存在：{}", item.getTicketId(), ticket != null);
                if (ticket == null) {
                    throw new CustomException(400, "门票信息不存在（ticketId：" + item.getTicketId() + "）");
                }
                // 2. 门票时间信息检查（确保非空）
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                Date now = new Date();
                if (ticket.getTicketStartrq() == null || ticket.getTicketEndrq() == null) {
                    throw new CustomException(400, "门票时间信息不完整（ticketId：" + item.getTicketId() + 
                        "，名称：" + ticket.getTicketName() + "）");
                }
                // 检查游玩日期是否在门票有效期内
                if (order.getOrderYwrq() == null) {
                    throw new CustomException(400, "订单游玩日期不能为空");
                }
                if (order.getOrderYwrq().before(ticket.getTicketStartrq()) || 
                    order.getOrderYwrq().after(ticket.getTicketEndrq())) {
                    throw new CustomException(400, "选择的游玩日期不在门票有效期内（门票有效期：" + 
                        sdf.format(ticket.getTicketStartrq()) + " 至 " + sdf.format(ticket.getTicketEndrq()) +
                        "，选择日期：" + sdf.format(order.getOrderYwrq()) + "）");
                }
                if (ticket.getTicketStartrq().after(now) || ticket.getTicketEndrq().before(now)) {
                    throw new CustomException(400, "门票不在有效期内（ticketId：" + item.getTicketId() + 
                        "，名称：" + ticket.getTicketName() + 
                        "，有效期：" + sdf.format(ticket.getTicketStartrq()) + " 至 " + sdf.format(ticket.getTicketEndrq()) +
                        "，当前时间：" + sdf.format(now) + "）");
                }
            }

            // 3. 订单总金额/数量计算（加日志）
            int totalCount = orderItemList.stream().mapToInt(OrderItem::getQuantity).sum();
            BigDecimal totalPrice = orderItemList.stream()
                    .map(item -> item.getUnitPrice().multiply(new BigDecimal(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            order.setOrderCount(totalCount);
            order.setOrderTprice(totalPrice);
            log.info("计算订单总数量：{}，总金额：{}", totalCount, totalPrice);

            // 4. 如果订单号为空，则生成新的订单号
            if (order.getOrderNo() == null || order.getOrderNo().trim().isEmpty()) {
                order.setOrderNo(OrderUtil.generateOrderNo());
                log.info("生成新的订单号：{}", order.getOrderNo());
            } else {
                log.info("使用传入的订单号：{}", order.getOrderNo());
            }

            // 5. 插入订单主表（加日志，确认订单参数）
            log.info("准备插入订单：orderNo={}, visitorId={}, orderState={}",
                    order.getOrderNo(), order.getVisitorId(), order.getOrderState());
            
            // 验证必要字段
            if (order.getVisitorId() == null) {
                throw new CustomException(400, "游客ID不能为空");
            }
            if (order.getOrderYwrq() == null) {
                throw new CustomException(400, "游玩日期不能为空");
            }
            if (order.getOrderPtype() == null || order.getOrderPtype().isEmpty()) {
                throw new CustomException(400, "支付方式不能为空");
            }
            if (order.getOrderQpname() == null || order.getOrderQpname().isEmpty()) {
                throw new CustomException(400, "取票人姓名不能为空");
            }
            if (order.getOrderQprsj() == null || order.getOrderQprsj().isEmpty()) {
                throw new CustomException(400, "取票人手机号不能为空");
            }
            if (order.getOrderState() == null || order.getOrderState().isEmpty()) {
                throw new CustomException(400, "订单状态不能为空");
            }
            
            // 确保订单状态默认为"待付款"
            if (order.getOrderState() == null) {
                order.setOrderState("11"); // 待付款状态
            }
            
            int orderCount = orderDao.insert(order);
            if (orderCount <= 0) {
                throw new CustomException(500, "订单主表插入失败（影响行数为0，orderNo：" + order.getOrderNo() + "）");
            }

            // 6. 订单项关联订单ID（加日志，确认orderId是否生成）
            Integer generatedOrderId = order.getOrderId();
            log.info("订单插入后生成的orderId：{}", generatedOrderId);
            if (generatedOrderId == null || generatedOrderId <= 0) {
                throw new CustomException(500, "订单ID生成失败（orderId为空或无效，无法关联订单项）");
            }
            // 赋值orderId给所有订单项
            orderItemList.forEach(item -> {
                item.setOrderId(generatedOrderId);
                log.info("订单项赋值orderId：item.ticketId={}, item.orderId={}", item.getTicketId(), item.getOrderId());
            });

            // 7. 批量插入订单项（加日志，确认插入结果）
            int itemCount = orderItemDao.batchInsert(orderItemList);
            log.info("订单项批量插入结果：影响行数={}，预期行数={}", itemCount, orderItemList.size());
            if (itemCount != orderItemList.size()) {
                throw new CustomException(500, "订单项插入数量不匹配（预期插入" + orderItemList.size() + "条，实际插入" + itemCount + "条）");
            }

            return orderCount;
        } catch (CustomException e) {
            // 捕获自定义异常，直接抛出（保留原信息）
            log.error("订单插入业务异常：{}", e.getMessage() != null ? e.getMessage() : "无错误信息", e);
            throw e;
        } catch (Exception e) {
            // 捕获其他异常（如SQL异常），补充详细信息
            String errorMsg = "订单插入系统异常：" + e.getClass().getSimpleName() + "，原因：" + (e.getMessage() != null ? e.getMessage() : "未知错误");
            log.error(errorMsg, e); // 打印完整堆栈，包含SQL错误
            throw new CustomException(500, errorMsg);
        }
    }



    @Override
    public int update(Order order) {
        // 若需更新订单详情，需先删除原详情，再重新插入新详情（此处暂不实现，可根据业务扩展）
        return orderDao.update(order);
    }



    @Override
    public int updateOrderStateByNo(String orderNo, OrderStateEnum targetState) {
        if (orderNo == null || orderNo.trim().isEmpty()) {
            throw new CustomException(400, "订单号不可为空");
        }
        if (targetState == null) {
            throw new CustomException(400, "订单状态不可为空");
        }

        Order order = new Order();
        order.setOrderNo(orderNo);
        order.setOrderState(targetState.getCode()); // 直接使用枚举的code

        // 如果订单状态是"已付款"，则生成取票验证码
        if (targetState == OrderStateEnum.PAID_SUCCESS) {
            // 查询当前订单信息
            Order currentOrder = orderDao.queryByNo(orderNo);
            if (currentOrder != null) {
                // 只有当前订单状态不是已付款状态时才生成新的验证码
                if (!OrderStateEnum.PAID_SUCCESS.getCode().equals(currentOrder.getOrderState())) {
                    // 生成6位随机数字验证码
                    String verificationCode = String.format("%06d", new Random().nextInt(1000000));
                    order.setTicketVerificationCode(verificationCode);
                } else {
                    // 如果订单已经是已付款状态，则保留原有的验证码
                    order.setTicketVerificationCode(currentOrder.getTicketVerificationCode());
                }
            }
        } 
        // 如果订单状态是"已取票"，则保留原有的取票验证码
        else if (targetState == OrderStateEnum.TICKET_TAKEN) {
            // 查询当前订单信息
            Order currentOrder = orderDao.queryByNo(orderNo);
            if (currentOrder != null) {
                // 保留原有的验证码
                order.setTicketVerificationCode(currentOrder.getTicketVerificationCode());
            }
        }
        
        int affectRows = orderDao.updateStateByNo(order);

        if (affectRows == 0) {
            throw new CustomException(404, "未找到订单号为[" + orderNo + "]的订单");
        }
        return affectRows;
    }

    // 删除订单：级联删除详情（添加事务）
    @Override
    @Transactional
    public int deleteById(Integer orderId) {
        if (orderId == null || orderId <= 0) {
            throw new CustomException(400, "订单ID无效");
        }

        // 1. 先删除订单详情
        orderItemDao.deleteByOrderId(orderId);

        // 2. 再删除订单主表
        return orderDao.deleteById(orderId);
    }

    @Override
    public List<Order> queryByOrderState(String orderState) {
        return orderDao.queryByOrderState(orderState);
    }

    @Override
    public List<Order> queryByOrderStateAndCreateTimeBefore(String orderState, Date createTime) {
        return orderDao.queryByOrderStateAndCreateTimeBefore(orderState, createTime);
    }
    
    @Override
    public List<Order> queryByVisitorId(Integer visitorId) {
        if (visitorId == null || visitorId <= 0) {
            throw new CustomException(400, "游客ID无效");
        }
        List<Order> orders = orderDao.queryByVisitorId(visitorId);
        // 处理订单项中的门票和景区信息
        if (orders != null) {
            orders.forEach(order -> {
                if (order.getOrderItemList() != null) {
                    order.getOrderItemList().forEach(item -> {
                        if (item.getTicket() != null) {
                            // 确保门票关联了景区信息
                            if (item.getTicket().getScenic() == null && item.getTicket().getScenicId() != null) {
                                Scenic scenic = scenicService.queryById(item.getTicket().getScenicId());
                                item.getTicket().setScenic(scenic);
                            }
                        }
                    });
                }
            });
        }
        return orders;
    }
    
    @Override
    public boolean verifyTicket(String orderNo, String verificationCode) {
        // 参数校验
        if (orderNo == null || orderNo.trim().isEmpty()) {
            throw new CustomException(400, "订单号不能为空");
        }
        if (verificationCode == null || verificationCode.trim().isEmpty()) {
            throw new CustomException(400, "验证码不能为空");
        }
        
        // 查询订单
        Order order = orderDao.queryByNo(orderNo);
        if (order == null) {
            throw new CustomException(404, "订单不存在");
        }
        
        // 检查订单状态是否为"已付款"
        if (!OrderStateEnum.PAID_SUCCESS.getCode().equals(order.getOrderState())) {
            throw new CustomException(400, "订单状态异常，只有已付款的订单才能进行核销");
        }
        
        // 验证验证码
        if (verificationCode.equals(order.getTicketVerificationCode())) {
            // 更新订单状态为"已取票"
            Order updateOrder = new Order();
            updateOrder.setOrderNo(orderNo);
            updateOrder.setOrderState(OrderStateEnum.TICKET_TAKEN.getCode());
            orderDao.updateStateByNo(updateOrder);
            return true;
        }
        
        return false;
    }

}